package com.dtyunxi.admin.config.root;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Lists;

@Configuration
//@ImportResource("classpath:config/rpc/*.xml")
@PropertySource({ "classpath:config/config.properties" })
@ComponentScan(basePackages = { "com.project" })
@EnableTransactionManagement
public class RootContextConfig {
	
	private static final Logger logger = LoggerFactory.getLogger(RootContextConfig.class);

	@Autowired
	Environment env;
	
	@Bean(destroyMethod = "close")
	public DataSource dataSource() throws SQLException {

		String jdbcUrl = env.getProperty("jdbc_url");
		String jdbcUserName = env.getProperty("jdbc_username");
		String jdbcPassword = env.getProperty("jdbc_password");
		String validationQuery = env.getProperty("validationQuery");

		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(jdbcUrl);
		dataSource.setUsername(jdbcUserName);
		dataSource.setPassword(jdbcPassword);

		dataSource.setInitialSize(5); // 初始化连接大小
		dataSource.setMaxActive(20); // 连接池最大使用连接数量
		// dataSource.setMaxIdle(20);//连接池最大空闲
		dataSource.setMinIdle(0); // 连接池最小空闲
		dataSource.setMaxWait(60000); // 获取连接最大等待时间
		dataSource.setValidationQuery(validationQuery);
		dataSource.setTestOnBorrow(false);
		dataSource.setTestOnReturn(false);
		dataSource.setTestWhileIdle(true);
		dataSource.setTimeBetweenEvictionRunsMillis(60000); // 间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		dataSource.setMinEvictableIdleTimeMillis(25200000); // 一个连接在池中最小生存的时间，单位是毫秒
		dataSource.setRemoveAbandoned(true);
		dataSource.setRemoveAbandonedTimeout(1800); // 1800秒，也就是30分钟
		dataSource.setLogAbandoned(true); // 关闭abanded连接时输出错误日志
		dataSource.setFilters("mergeStat"); // 监控数据库
		dataSource.setConnectionInitSqls(Lists.newArrayList("set names utf8mb4;"));

		dataSource.init();

		return dataSource;
	}
	
	@Bean
	public SessionFactory sessionFactory(DataSource dataSource) throws Exception {
		LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource);
		builder.scanPackages("com.project.entity");
		// builder.setProperty("hibernate.default_schema", "dbo");
		builder.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto", "none"));
		builder.setProperty("hibernate.dialect",
				env.getProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"));
		builder.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql", "true"));
		builder.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql", "false"));
//		builder.setProperty("hibernate.current_session_context_class","thread");
//		builder.setProperty("hibernate.current_session_context_class","org.springframework.orm.hibernate5.SpringSessionContext");
		builder.setProperty("hibernate.cache.use_query_cache", "true"); // 开启查询缓存
		builder.setProperty("hibernate.cache.use_second_level_cache", "true"); // 开启二级缓存
		// 高速缓存提供程序
		// 由于spring也使用了Ehcache, 保证双方都使用同一个缓存管理器
		builder.setProperty("hibernate.cache.region.factory_class", env.getProperty(
				"hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"));
		
		return builder.buildSessionFactory();
	}

	@Bean
	public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) throws Exception {
		HibernateTransactionManager manager = new HibernateTransactionManager();
		manager.setSessionFactory(sessionFactory);
		return manager;
	}
	
}
